package com.qf.courtesycard.user.service.impl;


import cn.hutool.jwt.JWT;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qf.courtesycard.user.entity.User;
import com.qf.courtesycard.user.mapper.UserMapper;
import com.qf.courtesycard.user.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.nio.charset.StandardCharsets;
import java.util.Date;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author lx
 * @since 2023-03-10
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public String checkToken(String name, String phoneNum) throws Exception {
        //从redis中获取token
        String jwtToken = (String) redisTemplate.opsForValue().get("userToken:" + phoneNum);
        if (jwtToken != null) {
            return jwtToken;
        } else {
            String userToken = getUserToken(name, phoneNum);
            return userToken;
        }
    }


    public String getUserToken(String name, String phoneNum) throws Exception {
        String newToken = createToken(phoneNum);
        //将生成的token存入redis缓存
        redisTemplate.opsForValue().set("userToken:" + phoneNum, newToken);
        //将用户信息落库
        saveUser(name, phoneNum);
        return newToken;
    }

    /**
     * 查询用户
     *
     * @param phoneNum
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.SUPPORTS)
    public User getUser(String phoneNum) {
        User user = getOne(new LambdaQueryWrapper<User>().eq(User::getPhone, phoneNum));
        return user;
    }

    /**
     * 保存用户信息
     *
     * @param name     用户名
     * @param phoneNum 电话号码
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveUser(String name, String phoneNum) throws Exception {
        //用户第一次获取token时保存用户信息
        User userDB = getUser(phoneNum);
        if (userDB == null) {
            User user = new User();
            user.setName(name);
            user.setPhone(phoneNum);
            save(user);
        } else {
            throw new Exception("手机号重复");
        }
    }

    /**
     * 生成token,5分钟过期
     *
     * @param phoneNum 电话号码
     * @return
     */
    private String createToken(String phoneNum) {
        String token = JWT.create().setPayload("phoneNum", phoneNum).setExpiresAt(new Date(System.currentTimeMillis() + 1000 * 60 * 5))
                .setKey("qfjava2203".getBytes(StandardCharsets.UTF_8)).sign();
        return token;
    }
}
